package cn.zyx.common.utils.sys;

import cn.zyx.common.properites.CacheProperties;
import cn.zyx.common.utils.cache.redis.RedisUtils;
import cn.zyx.sys.entity.*;
import cn.zyx.sys.mapper.AccessKeyMapper;
import cn.zyx.sys.mapper.MenuMapper;
import cn.zyx.sys.mapper.RoleMapper;
import cn.zyx.sys.mapper.UserMapper;
import cn.zyx.sys.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.UnavailableSecurityManagerException;
import org.apache.shiro.session.InvalidSessionException;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.assertj.core.util.Lists;

import java.util.List;

public class UserUtils {

    /**
     * 是否有权限
     * @param permission
     * @return
     */
    public static boolean hasPermission(String permission){
        return SecurityUtils.getSubject().isPermitted(permission);
    }


    /**
     * 获取授权主要对象
     * @return
     */
    public static Subject getSubject(){
        return SecurityUtils.getSubject();
    }

    /**
     * 获取用户信息
     * @return
     */
    public static User getUser(){
        String token = getToken();
        if (token != null){
            User user = getByLoginName(JWTUtils.getLoginName(token));
            if (user != null){
                return user;
            }
            return new User ();
        }
        // 如果没有登录，则返回实例化空的User对象。
        return new User ();
    }

    /**
     * 获取当前登录者对象的token
     */
    public static String getToken(){
        try{
            Subject subject = SecurityUtils.getSubject();
            // 获取登录Subject的用户名
            Object token = subject.getPrincipal();
            if (token != null){
                return token.toString();
            }
        } catch (UnavailableSecurityManagerException | InvalidSessionException ignored) {

        }
        return null;
    }

    /**
     * 根据登录名获取用户
     * @param loginName
     * @return 取不到返回null
     */
    public static User getByLoginName(String loginName){
        User user = RedisUtils.getCacheObject(CacheProperties.USER_CACHE + CacheProperties.USER_CACHE_LOGIN_NAME_ + loginName);
        if (user == null){
            user = SpringContextHolderUtils.getBean(UserMapper.class).getByLoginName(new User (null, loginName));
            if (user == null){
                return null;
            }
            RedisUtils.setCacheObject(CacheProperties.USER_CACHE + CacheProperties.USER_CACHE_ID_ + user.getId(), user);
            RedisUtils.setCacheObject(CacheProperties.USER_CACHE + CacheProperties.USER_CACHE_LOGIN_NAME_ + user.getLoginName(), user);
        }
        return user;
    }

    /**
     * accessKeyId 获取access对象
     * @param accessKeyId
     * @return 取不到返回null
     */
    public static AccessKey getInfoByAccessKeyId(String accessKeyId) {
        AccessKey accessKey = RedisUtils.getCacheObject(CacheProperties.ACCESS_KEY_CACHE + accessKeyId);
        if (accessKey == null){
            accessKey = SpringContextHolderUtils.getBean(AccessKeyMapper.class).getInfoByAccessKeyId(accessKeyId);
            if (accessKey == null){
                return null;
            }
            RedisUtils.setCacheObject(CacheProperties.ACCESS_KEY_CACHE + accessKey.getAccessKeyId(), accessKey);
        }
        return accessKey;
    }

    /**
     * 获取当前用户授权菜单
     * @return
    */
    public static List<Menu> getMenuList(){
        UserService service =  SpringContextHolderUtils.getBean(UserService.class);
        List<Menu> menuList = (List<Menu>)getCache(CacheProperties.CACHE_MENU_LIST);
        if (menuList == null){
            User user = getUser();
            if (user.isSuperUser(service.getSuperUser())){
                menuList = SpringContextHolderUtils.getBean(MenuMapper.class).findAllList(new Menu());
            }else{
                Menu m = new Menu ();
                m.setUserId(user.getId());
                menuList = SpringContextHolderUtils.getBean(MenuMapper.class).findByUserId(m);
            }
            putCache(CacheProperties.CACHE_MENU_LIST, menuList);
        }
        return menuList;
    }

    /**
     * 根据ID获取用户
     * @param id
     * @return 取不到返回null
     */
    public static User get(String id){
        User user = RedisUtils.getCacheObject(CacheProperties.USER_CACHE + CacheProperties.USER_CACHE_ID_ + id);
        if (user ==  null){
            user = SpringContextHolderUtils.getBean(UserMapper.class).get(id);
            if (user == null){
                return null;
            }
            RedisUtils.setCacheObject(CacheProperties.USER_CACHE + CacheProperties.USER_CACHE_ID_ + user.getId(), user);
            RedisUtils.setCacheObject(CacheProperties.USER_CACHE + CacheProperties.USER_CACHE_LOGIN_NAME_ + user.getLoginName(), user);
        }
        return user;
    }

    public static String getUserNameById(String id){
        User user = get(id);
        if(user == null){
            return "";
        }else{
            return user.getName();
        }
    }

    /**
     * 清除指定用户缓存
     */
    public static void clearCache(User user){
        RedisUtils.deleteObject(CacheProperties.USER_CACHE + CacheProperties.USER_CACHE_ID_ + user.getId());
        RedisUtils.deleteObject(CacheProperties.USER_CACHE + CacheProperties.USER_CACHE_LOGIN_NAME_ + user.getLoginName());
        RedisUtils.deleteObject(CacheProperties.USER_CACHE + CacheProperties.USER_CACHE_LOGIN_NAME_ + user.getOldLoginName());
        if (user.getOffice() != null && user.getOffice().getId() != null){
            RedisUtils.deleteObject(CacheProperties.USER_CACHE + CacheProperties.USER_CACHE_LIST_BY_OFFICE_ID_ + user.getOffice().getId());
        }
    }


    /**
     * 获取当前用户
     * @return 取不到返回 new User()
     */
    public static User getCasUser(){
        String token = getToken();
        if (token!=null){
            User user = getByLoginName(JWTUtils.getLoginName(token));
            if (user != null){
                return user;
            }
            return new User ();
        }
        // 如果没有登录，则返回实例化空的User对象。
        return new User ();
    }

    /**
     * 获取当前用户角色列表
     * @return
     */
    public static List<Role> getRoleList(){
        UserService IUserService=  SpringContextHolderUtils.getBean(UserService.class);
        List<Role> roleList = (List<Role>)getCache(CacheProperties.CACHE_ROLE_LIST);
        if (roleList == null){
            User user = getUser();
            if (user.isSuperUser((IUserService.getSuperUser()))){
                roleList = SpringContextHolderUtils.getBean(RoleMapper.class).findAllList(new Role ());
            }else{
                roleList = user.getRoleList();
            }
            putCache(CacheProperties.CACHE_ROLE_LIST, roleList);
        }
        return roleList;
    }

    /**
     *获取当前用户授权数据权限
     *      * @return
     */
    public static List<DataRule> getDataRuleList(){
        @SuppressWarnings("unchecked")
        UserService IUserService=  SpringContextHolderUtils.getBean(UserService.class);
        List<DataRule> dataRuleList = (List<DataRule>)getCache(CacheProperties.CACHE_DATA_RULE_LIST);
        if (dataRuleList == null){
            User user = getUser();
            if (user.isSuperUser(IUserService.getSuperUser())){
                dataRuleList = Lists.newArrayList();
            } else {
                // todo -------
                dataRuleList = Lists.newArrayList();
                //dataRuleList = SpringContextHolderUtils.getBean(DataRuleMapper.class).findByUserId(user);
            }
            putCache(CacheProperties.CACHE_DATA_RULE_LIST, dataRuleList);
        }
        return dataRuleList;
    }


    /**
     * 获取当前用户授权菜单
     * @return
     */
    public static Menu getTopMenu() {
        Menu topMenu = (Menu) getCache(CacheProperties.CACHE_TOP_MENU);
        if (topMenu == null) {
            topMenu = SpringContextHolderUtils.getBean(MenuMapper.class).get("1");
            putCache(CacheProperties.CACHE_TOP_MENU, topMenu);
        }
        return topMenu;
    }

    /**
     * 获取当前用户授权的区域
     * @return
     */
    /*public static List<Area> getAreaList(){
        @SuppressWarnings("unchecked")
        List<Area> areaList = (List<Area>)getCache(CACHE_AREA_LIST);
        if (areaList == null){
            areaList = SpringContextHolderUtils.getBean(AreaMapper.class).findAllList(new Area ());
            putCache(CACHE_AREA_LIST, areaList);
        }
        return areaList;
    }*/

    /**
     *
     * 获取当前用户有权限访问的部门
     * @return
     */
    public static List<Office> getOfficeList(){
        /*@SuppressWarnings("unchecked")
        UserService IUserService=  SpringContextHolderUtils.getBean(UserService.class);
        List<Office> officeList = (List<Office>)getCache(CACHE_OFFICE_LIST);
        if (officeList == null){
            User user = getUser();
            if (user.isSuperUser(IUserService.GetsuperUser())){
                officeList = SpringContextHolderUtils.getBean(OfficeMapper.class).findAllList(new Office ());
            }else{
                Office office = new Office ();
                //BaseService.dataRuleFilter(office);
                officeList = SpringContextHolderUtils.getBean(OfficeMapper.class).findList(office);
            }
            putCache(CACHE_OFFICE_LIST, officeList);
        }
        return officeList;*/
        return null;
    }

    /**
     * 获取当前用户有权限访问的部门
      * @return
     */
    public static List<Office> getOfficeAllList(){
       /* @SuppressWarnings("unchecked")
        List<Office> officeList = (List<Office>)getCache(CACHE_OFFICE_ALL_LIST);
        if (officeList == null){
            officeList = SpringContextHolderUtils.getBean(OfficeMapper.class).findAllList(new Office ());
        }
        return officeList;*/
        return null;
    }

    
    public static List<Office> findOfficeAllList(Office office){

        /*List<Office>  officeList = SpringContextHolderUtils.getBean(OfficeMapper.class).findAllList(office);

        return officeList;*/

        return null;
    }



    public static Session getSession(){
        try{
            Subject subject = SecurityUtils.getSubject();
            Session session = subject.getSession(false);
            if (session == null){
                session = subject.getSession();
            }
            if (session != null){
                return session;
            }
//			subject.logout();
        }catch (InvalidSessionException e){

        }
        return null;
    }


    // 根据key，获取和当前用户的缓存
    public static Object getCache(String key) {
        Object obj = RedisUtils.getCacheObject(CacheProperties.USER_CACHE + key + CacheProperties.CACHE_SPLIT + getUser ().getId ());
        return obj;
    }

    // 设置当前用户的缓存
    public static void putCache(String key, Object value) {
        RedisUtils.setCacheObject(CacheProperties.USER_CACHE + key + CacheProperties.CACHE_SPLIT + getUser().getId (), value);
    }

    /**
     * 清除当前用户缓存
     */
    public static void clearCache(){
        removeCache(CacheProperties.CACHE_ROLE_LIST);
        removeCache(CacheProperties.CACHE_DATA_RULE_LIST);
        removeCache(CacheProperties.CACHE_TOP_MENU);
        removeCache(CacheProperties.CACHE_MENU_LIST);
        removeCache(CacheProperties.CACHE_AREA_LIST);
        removeCache(CacheProperties.CACHE_OFFICE_LIST);
        removeCache(CacheProperties.CACHE_OFFICE_ALL_LIST);
        UserUtils.clearCache(getUser());
    }

    // 清除当前用户的缓存
    public static void removeCache(String key) {
        RedisUtils.deleteObject(CacheProperties.USER_CACHE + key + CacheProperties.CACHE_SPLIT +getUser ().getId ());
    }


}
